package ru.spb.nicetu.altx.mnemo.utils.widgets;

import java.util.ArrayList;

import org.eclipse.jface.fieldassist.ControlDecoration;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.FocusListener;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Text;

import ru.spb.nicetu.altx.mnemo.utils.TextUtils;

/**
 * Текстовое поле ввода для редактирования Double-значений
 */
public class DoubleTextFieldComposite extends AFieldComposite{

  //**************************************************************************//
  //                        Enums                                             //
  //**************************************************************************//

  //**************************************************************************//
  //                        Members                                           //
  //**************************************************************************//
	  /**
	   * собствено, поле ввода
	   */
	  private Text mDoubleText;
	/**
   * последнее из double-значений, введенных корректно
   */
  private Double mLastCorrectDoubleValue;
  /**
   * текстовое представление последнего корректного double-значения (то как
   * его ввел пользователь)
   */
  private String mLastCorrectStringValue;
  
  /**
   * Последнее введенное значение до enable/disable
   */
  private String mLastDoubleText = mLastCorrectStringValue;
  /**
   * Декоратор на поле для контроля корректного ввода 
   * вещественных значений
   */
  private ControlDecoration mTextDecoration;
  
  /**
   * Флаг корректности поля ввода
   */
  private boolean isCorrect;
  
  /**
   * Описание ошибки
   */
  private String mErrorDescription = "Введенное значение не является вещественным числом";

  //**************************************************************************//
  //                        Constructors                                      //
  //**************************************************************************//
  public DoubleTextFieldComposite(Composite parent, int style) {
    super(parent, style);
  }
  //**************************************************************************//
  //                        Getters                                           //
  //**************************************************************************//

  //**************************************************************************//
  //                        Setters                                           //
  //**************************************************************************//

  //**************************************************************************//
  //                        Publics                                           //
  //**************************************************************************//
  @Override
  public void addFieldModifyListener(final ModifyListener listener) {
    mDoubleText.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent e) {
        e.data = DoubleTextFieldComposite.this;
        listener.modifyText(e);
      }
    });
  }
  
  @Override
	public void setFieldEnable(boolean enable) {
	    mDoubleText.setEnabled(enable);
		//чтобы сработал модифайЛистнер
		if (enable) {
			//для редактора, когда надо показать поля, для которых mLastText==null
			mDoubleText.setText( (mLastDoubleText!=null) ? mLastDoubleText : mLastCorrectStringValue);
		}
		else {
			setCorrect(true);
			mLastDoubleText = mDoubleText.getText();
			mDoubleText.setText(mLastDoubleText);
		}
	}
  
  @Override
	public Boolean isCorrect() {
		return (isCorrect);
	}

  @Override
    public String getErrorDescription() {
		return mErrorDescription;
	}

  /**
   * @return последнее из double-значений, введенных корректно
   */
  public Double getDoubleValue() {
    return mLastCorrectDoubleValue;
  }

  /**
   * задать в поле ввода новое текущее double-значение
   */
  public void setDoubleValue(Double val) {
    if (val == null) {
    	mLastCorrectDoubleValue = 0.0d;
        mLastCorrectStringValue = doubleToString(mLastCorrectDoubleValue);

        setText(mLastCorrectStringValue);
    } else {
      mLastCorrectDoubleValue = val;
      mLastCorrectStringValue = doubleToString(mLastCorrectDoubleValue);

      setText(mLastCorrectStringValue);
    }
  }
  
  @Override
  public void setFieldLayoutData(Object data) {
    mDoubleText.setLayoutData(data);
    layout();
  }
  //**************************************************************************//
  //                        Abstracts                                         //
  //**************************************************************************//

  public void setText(String val) {
	    if (val == null) {
	    	val="";
//	      return;
	    }
	    mLastCorrectStringValue = val;
	    mDoubleText.setText(mLastCorrectStringValue);
  }
  //**************************************************************************//
  //                        Protected                                         //
  //**************************************************************************//
  @Override
  protected void createControls(Composite parent, int style) {
    mDoubleText = new Text(this, style | SWT.BORDER);

    mDoubleText.addModifyListener(new ModifyListener() {
      public void modifyText(ModifyEvent evt) {
    	setCorrect(true);
        try {
          String txt = mDoubleText.getText();
          Double d = Double.parseDouble(txt);

          mLastCorrectDoubleValue = d;

          mLastCorrectStringValue = (d==null) ? "" : doubleToString(mLastCorrectDoubleValue);
          
        } catch (NumberFormatException e) {
        	if (mDoubleText.isEnabled()) setCorrect(false);
        }
      }
    });
    mTextDecoration = createDecorator(mDoubleText);
  }
  
  @Override
	protected ControlDecoration createDecorator(Control control) {
	  ControlDecoration c = super.createDecorator(control);
	  c.setDescriptionText(mErrorDescription);
	  return c;
	}
  
  public void selectAll(){
    mDoubleText.selectAll();
  }
  
  //**************************************************************************//
  //                        Privates                                          //
  //**************************************************************************//

  private void setCorrect(boolean enable){
	  isCorrect = enable;
	  if (enable) {
		mTextDecoration.hide();
	  } else {
		mTextDecoration.show();
	  }
  }
  //**************************************************************************//
  //                        Public Statics                                    //
  //**************************************************************************//

  //**************************************************************************//
  //                        Private Statics                                   //
  //**************************************************************************//
  private static String doubleToString(Double val) {
    //  return val.toString();
    return TextUtils.convertDoubleToString(val);
  }
  //**************************************************************************//
  //                        Internal Classes                                  //
  //**************************************************************************//

@Override
public boolean getFieldEnable() {
	return mDoubleText.isEnabled();
}
}
